package tech.summerly.weather.component.fragments

import android.Manifest
import android.arch.lifecycle.ViewModelProviders
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.SearchView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.fragment_region_selector.*
import kotlinx.android.synthetic.main.fragment_region_selector.view.*
import kotlinx.android.synthetic.main.item_city.view.*
import kotlinx.android.synthetic.main.item_region_header.view.*
import org.jetbrains.anko.support.v4.toast
import tech.summerly.weather.R
import tech.summerly.weather.component.viewmodel.RegionViewModel
import tech.summerly.weather.model.Region
import tech.summerly.weather.util.*

/**
 * the container of [RegionSelectorFragment] need to implement [RegionSelectorFragment.Container]
 */
class RegionSelectorFragment : Fragment() {


    private val mRegionViewModel by lazy {
        ViewModelProviders.of(this, RegionViewModel).get(RegionViewModel::class.java)
    }

    private val mRegionAdapter by lazy { RegionListAdapter() }

    private val mQueryTextListener = object : SearchView.OnQueryTextListener {
        override fun onQueryTextSubmit(query: String): Boolean {
            return false
        }

        override fun onQueryTextChange(newText: String): Boolean {
            mRegionViewModel.searchRegion(newText)
            return true
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        subscribeUI()
    }

    private fun subscribeUI() {
        mRegionViewModel.searchResult.observe(this) { result ->
            if (result == null) {
                return@observe
            }
            val (regions, query) = result
            mRegionAdapter.setRegions(regions)
            //更新searchView中的关键词
            view?.searchView?.apply {
                if (query != getQuery()) {
                    setQuery(query, false)
                }
            }
        }
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_region_selector, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) = with(view) {
        buttonBack.setOnclickListenerSafely {
            closeSelf()
        }
        buttonLocation.setOnclickListenerSafely {
            if (activity?.requestPermission(Manifest.permission.ACCESS_FINE_LOCATION) != true) {
                toast(string(R.string.need_locaiton_permission))
                return@setOnclickListenerSafely
            }
            val region = activity?.getLocationWithDialog()
            if (region == null) {
                toast(string(R.string.can_not_get_location))
            } else {
                onRegionSelected(region)
            }
        }
        searchView.isIconified = false
        searchView.setOnQueryTextListener(mQueryTextListener)
        recyclerRegions.adapter = mRegionAdapter
        mRegionAdapter.setRegions(mRegionViewModel.getAllRegion())
    }


    private fun onRegionSelected(region: Region) {
        (activity as? Container)?.onRegionSelected(region)
    }


    override fun onStop() {
        searchView.clearFocus()
        super.onStop()
    }

    private enum class Type {
        HEADER,
        REGION
    }

    /**
     * 区域列表适配器
     */
    inner class RegionListAdapter : RecyclerView.Adapter<ViewHolder>() {

        private val items = ArrayList<Any>()


        fun setRegions(regions: List<Region>) {
            items.clear()
            val provinceGroup = regions.groupBy { it.province }
            provinceGroup.keys.forEach { key ->
                items.add(key)
                provinceGroup[key]?.let { items.addAll(it) }
            }
            notifyDataSetChanged()
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
            val inflater = LayoutInflater.from(parent.context)
            return when (viewType) {
                Type.REGION.ordinal -> {
                    ViewHolder(R.layout.item_city, parent, inflater)
                }
                Type.HEADER.ordinal -> {
                    ViewHolder(R.layout.item_region_header, parent, inflater)
                }
                else -> error("error view type $viewType")
            }
        }

        override fun getItemCount(): Int {
            return items.size
        }

        override fun getItemViewType(position: Int): Int {
            return when (items[position]) {
                is String -> Type.HEADER.ordinal
                is Region -> Type.REGION.ordinal
                else -> error("error to get type : ${items[position]}")
            }
        }

        override fun onBindViewHolder(holder: ViewHolder, position: Int) {
            when (getItemViewType(position)) {
                Type.HEADER.ordinal -> {
                    bindViewForHeader(holder, items[position] as String)
                }
                Type.REGION.ordinal -> {
                    bindViewForRegion(holder, items[position] as Region)
                }
            }
        }

        private fun bindViewForHeader(holder: ViewHolder, province: String) {
            holder.itemView.textHeader.text = province
        }

        private fun bindViewForRegion(holder: ViewHolder, region: Region) = with(holder.itemView) {
            textCity.text = region.name
            setOnClickListener {
                onRegionSelected(region)
            }
        }
    }


    interface Container {

        /**
         * 当一个区域被选择了
         */
        fun onRegionSelected(region: Region)
    }

}